package network_programming.np1_socket_and_serversocket;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;

/**
 * 利用JDK类库提供的线程池Executor接口来完成与客户端的通信任务
 * Executor在java.util.concurrent包下定义
 *
 * */
public class EchoServerExecutor {
    private int port = 9099;        // 监听的端口号
    private final ServerSocket serverSocket;
    private ExecutorService executorService;    // 线程池
    private final int POOL_SIZE = 4;    // 单个CUP时线程池中工作线程的数目

    public EchoServerExecutor() throws IOException {
        serverSocket = new ServerSocket(port);
        executorService = Executors.newFixedThreadPool(
                Runtime.getRuntime().availableProcessors() * POOL_SIZE);
        System.out.println("服务器已启动");
    }

    public void service() {
        while(true) {
            try {
                Socket socket = serverSocket.accept();
                executorService.execute(new EchoServerHandler(socket));		// 把与客户通信的任务交给线程池
            } catch (SocketTimeoutException e) {
                // 不必处理等待客户连接超时时的异常
            } catch (RejectedExecutionException e) {
                return;
            } catch (SocketException e) {
                // 如果是在执行serverSocket.accept()方法时，被ShutdownThread线程关闭而导致的异常，则退出service()方法
                if(e.getMessage().contains("socket closed"))
                    return;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws IOException {
        new EchoServerExecutor().service();
    }
}
